// Package bootstrap 处理程序初始化逻辑
package bootstrap

import (
	"fmt"
	"gohub/app/http/middlewares"
	"gohub/routes"
	"net/http"
	"os"
	"path/filepath"
	"strings"

	"github.com/gin-gonic/gin"
)

// SetupRoute 路由初始化
func SetupRoute(router *gin.Engine) {
	// 注册 ws 路由
	//routes.RegisterWsRoute(router)
	routes.SetupWsRouters(router)

	// 注册全局中间件
	registerGlobalMiddleWare(router)

	// 设置静态文件路由（将public作为根目录）
	setupStaticRouter(router, "/uploads", "./public/uploads")

	// 注册 API 路由
	routes.RegisterAPIRoutes(router)

	// 配置 404 路由
	setup404Handler(router)
}

func registerGlobalMiddleWare(router *gin.Engine) {
	router.Use(
		//gin.Logger(),
		//gin.Recovery(),
		middlewares.Logger(),
		middlewares.Recovery(),
		middlewares.ForceUA(),
	)
}

func setup404Handler(router *gin.Engine) {
	// 处理 404 请求
	router.NoRoute(func(c *gin.Context) {
		// 获取标头信息的 Accept 信息
		acceptString := c.Request.Header.Get("Accept")
		if strings.Contains(acceptString, "text/html") {
			// 如果是 HTML 的话
			c.String(http.StatusNotFound, "页面返回 404")
		} else {
			// 默认返回 JSON
			c.JSON(http.StatusNotFound, gin.H{
				"error_code":    404,
				"error_message": "路由未定义，请确认 url 和请求方法是否正确。",
			})
		}
	})
}

func setupStaticRouter(r *gin.Engine, urlPrefix string, localPath string) {
	// 使用Group添加中间件
	uploadsGroup := r.Group(urlPrefix)

	uploadsGroup.Use(func(c *gin.Context) {
		// 限制只允许特定扩展名
		ext := filepath.Ext(c.Request.URL.Path)
		allowedExts := map[string]bool{
			".png":  true,
			".jpg":  true,
			".jpeg": true,
			".gif":  true,
		}

		if !allowedExts[ext] {
			c.AbortWithStatus(http.StatusForbidden)
			return
		}

		// 验证Referer（可选）
		if c.GetHeader("Referer") == "" && !strings.HasPrefix(c.GetHeader("User-Agent"), "curl/") {
			c.AbortWithStatus(http.StatusForbidden)
			return
		}
	})

	// 自定义文件服务处理器
	uploadsGroup.GET("/*filepath", func(c *gin.Context) {
		// 1. 安全验证路径
		requestedPath := c.Param("filepath")
		fmt.Printf("=== requestedPath: %#v\n", requestedPath)
		if strings.Contains(requestedPath, "../") || strings.Contains(requestedPath, "\\") {
			c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "非法路径访问"})
			return
		}

		// 2. 构建完整文件路径
		fullPath := filepath.Join(localPath, requestedPath)
		fullPath = filepath.Clean(fullPath) // 规范化路径
		fmt.Printf("=== fullPath: %#v\n", fullPath)

		// 3. 验证文件是否存在
		if _, err := os.Stat(fullPath); os.IsNotExist(err) {
			c.AbortWithStatus(http.StatusNotFound)
			return
		}

		// 4. 设置缓存头（针对图片等静态资源）
		if strings.HasSuffix(fullPath, ".png") ||
			strings.HasSuffix(fullPath, ".jpg") ||
			strings.HasSuffix(fullPath, ".jpeg") {
			c.Header("Cache-Control", "public, max-age=31536000") // 1年缓存
		}
		c.Header("Content-Type", "image/vnd.microsoft.icon; charset=UTF-8")

		// 5. 返回文件
		c.File(fullPath)
	})
}
